using CommunityToolkit.Mvvm.Messaging;
using ImageCSharp.Core.Events;
using ImageCSharp.Core.Models;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Point = System.Windows.Point;
using ImageCSharp.Core.Services;

namespace ImageCSharp.Controls
{
    /// <summary>
    /// 图像画布控件
    /// </summary>
    public partial class ImageCanvas : UserControl, INotifyPropertyChanged, IRecipient<ImageDocumentChangedEvent>
    {
        #region Dependency Properties

        public static readonly DependencyProperty DocumentProperty =
            DependencyProperty.Register("Document", typeof(ImageDocument), typeof(ImageCanvas),
                new PropertyMetadata(null, OnDocumentChanged));

        public static readonly DependencyProperty SelectedToolProperty =
            DependencyProperty.Register("SelectedTool", typeof(Tool), typeof(ImageCanvas),
                new PropertyMetadata(null, OnSelectedToolChanged));

        public ImageDocument? Document
        {
            get => (ImageDocument?)GetValue(DocumentProperty);
            set => SetValue(DocumentProperty, value);
        }

        public Tool? SelectedTool
        {
            get => (Tool?)GetValue(SelectedToolProperty);
            set => SetValue(SelectedToolProperty, value);
        }

        #endregion

        #region Private Fields

        private Point _startPoint;
        private bool _isSelecting;
        private bool _isDrawing;
        private bool _isMeasuring;
        private SixLabors.ImageSharp.RectangleF _selectionRect;
        private WriteableBitmap? _bitmap;

        #endregion

        public ImageCanvas()
        {
            InitializeComponent();
            
            // 注册消息
            WeakReferenceMessenger.Default.Register<ZoomLevelChangedEvent>(this, (r, m) =>
            {
                UpdateImageScale();
            });

            // 设置事件处理
            Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            Focusable = true;
            Focus();
        }

        #region Property Changed Handlers

        private static void OnDocumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is ImageCanvas canvas)
            {
                canvas.UpdateImageDisplay();
            }
        }

        private static void OnSelectedToolChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is ImageCanvas canvas)
            {
                canvas.UpdateToolMode();
            }
        }

        #endregion

        #region Image Display

        private void UpdateImageDisplay()
        {
            if (Document?.Image == null)
            {
                MainImage.Source = null;
                return;
            }

            // 将ImageSharp图像转换为WPF BitmapSource
            _bitmap = ConvertToWriteableBitmap(Document.Image);
            MainImage.Source = _bitmap;
            
            UpdateImageScale();
        }

        private void UpdateImageScale()
        {
            if (Document == null || MainImage.Source == null) return;

            var scale = Document.ZoomLevel;
            MainImage.LayoutTransform = new ScaleTransform(scale, scale);
        }

        private WriteableBitmap ConvertToWriteableBitmap(Image<Rgba32> image)
        {
            var bitmap = new WriteableBitmap(
                image.Width, image.Height,
                96, 96, PixelFormats.Bgra32, null);

            var pixels = new byte[image.Width * image.Height * 4];
            
            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    var pixel = image[x, y];
                    int index = (y * image.Width + x) * 4;
                    
                    pixels[index] = pixel.B;     // Blue
                    pixels[index + 1] = pixel.G; // Green
                    pixels[index + 2] = pixel.R; // Red
                    pixels[index + 3] = pixel.A; // Alpha
                }
            }

            bitmap.WritePixels(
                new Int32Rect(0, 0, image.Width, image.Height),
                pixels, image.Width * 4, 0);

            return bitmap;
        }

        #endregion

        #region Tool Mode Management

        private void UpdateToolMode()
        {
            // 重置所有模式
            _isSelecting = false;
            _isDrawing = false;
            _isMeasuring = false;

            // 隐藏所有覆盖层
            SelectionRectangle.Visibility = Visibility.Collapsed;
            DrawingCanvas.Visibility = Visibility.Collapsed;
            MeasurementLine.Visibility = Visibility.Collapsed;
            MeasurementText.Visibility = Visibility.Collapsed;

            if (SelectedTool == null) return;

            switch (SelectedTool.Type)
            {
                case ToolType.Selection:
                    _isSelecting = true;
                    Cursor = Cursors.Cross;
                    break;

                case ToolType.Drawing:
                    _isDrawing = true;
                    DrawingCanvas.Visibility = Visibility.Visible;
                    Cursor = Cursors.Pen;
                    SetupDrawingCanvas();
                    break;

                case ToolType.Measurement:
                    _isMeasuring = true;
                    Cursor = Cursors.Cross;
                    break;

                default:
                    Cursor = Cursors.Arrow;
                    break;
            }
        }

        //private void SetupDrawingCanvas()
        //{
        //    if (SelectedTool is DrawingTool drawingTool)
        //    {
        //        var drawingAttributes = new System.Windows.Ink.DrawingAttributes
        //        {
        //            Color = System.Windows.Media.Color.FromArgb(
        //                (byte)(drawingTool.Color.A * drawingTool.Opacity),
        //                drawingTool.Color.R,
        //                drawingTool.Color.G,
        //                drawingTool.Color.B),
        //            Width = drawingTool.BrushSize,
        //            Height = drawingTool.BrushSize,
        //            FitToCurve = true,
        //            IgnorePressure = false
        //        };

        //        DrawingCanvas.DefaultDrawingAttributes = drawingAttributes;
        //    }
        //}



        private void SetupDrawingCanvas()
        {
            if (SelectedTool is DrawingTool drawingTool)
            {
                // 转换为 Rgba32 来访问 RGBA 分量
                var rgba = drawingTool.Color.ToPixel<Rgba32>();
                byte r = rgba.R;
                byte g = rgba.G;
                byte b = rgba.B;
                byte a = rgba.A; // 这是 alpha 通道

                // 正确转换：Rgba32 -> System.Windows.Media.Color
                var color = System.Windows.Media.Color.FromArgb(
                    a,  // Rgba32 的 A 字段（0-255）
                    r,  // Rgba32 的 R 字段
                    g,  // Rgba32 的 G 字段
                    b   // Rgba32 的 B 字段
                );

                var drawingAttributes = new System.Windows.Ink.DrawingAttributes
                {
                    Color = color,
                    Width = drawingTool.BrushSize,
                    Height = drawingTool.BrushSize,
                    FitToCurve = true,
                    IgnorePressure = false
                };

                DrawingCanvas.DefaultDrawingAttributes = drawingAttributes;
            }
        }
        #endregion

        #region Mouse Event Handlers

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            var position = e.GetPosition(MainImage);
            
            // 更新坐标显示
            if (Document?.Image != null)
            {
                var imagePos = GetImagePosition(position);
                CoordinateText.Text = $"X: {imagePos.X:0}, Y: {imagePos.Y:0}";
            }

            if (_isSelecting && e.LeftButton == MouseButtonState.Pressed)
            {
                UpdateSelectionRectangle(position);
            }
            else if (_isMeasuring && e.LeftButton == MouseButtonState.Pressed)
            {
                UpdateMeasurement(position);
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            Focus();

            if (e.LeftButton != MouseButtonState.Pressed) return;

            _startPoint = e.GetPosition(MainImage);

            if (_isSelecting)
            {
                StartSelection(_startPoint);
            }
            else if (_isMeasuring)
            {
                StartMeasurement(_startPoint);
            }
        }

        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            base.OnMouseUp(e);

            if (_isSelecting)
            {
                FinishSelection();
            }
            else if (_isMeasuring)
            {
                FinishMeasurement();
            }
        }

        #endregion

        #region Selection Logic

        private void StartSelection(Point startPoint)
        {
            _isSelecting = true;
            SelectionRectangle.Visibility = Visibility.Visible;
            
            //var imagePos = GetImagePosition(startPoint);
            Canvas.SetLeft(SelectionRectangle, startPoint.X);
            Canvas.SetTop(SelectionRectangle, startPoint.Y);
            SelectionRectangle.Width = 0;
            SelectionRectangle.Height = 0;
        }

        private void UpdateSelectionRectangle(Point currentPosition)
        {
            var left = Math.Min(_startPoint.X, currentPosition.X);
            var top = Math.Min(_startPoint.Y, currentPosition.Y);
            var width = Math.Abs(_startPoint.X - currentPosition.X);
            var height = Math.Abs(_startPoint.Y - currentPosition.Y);

            Canvas.SetLeft(SelectionRectangle, left);
            Canvas.SetTop(SelectionRectangle, top);
            SelectionRectangle.Width = width;
            SelectionRectangle.Height = height;
            SelectionRectangle.Visibility = Visibility.Visible;
            SelectionEllipse.Visibility = Visibility.Collapsed;

            // 更新选择区域
            var startImagePos = GetImagePosition(_startPoint);
            var currentImagePos = GetImagePosition(currentPosition);

            _selectionRect = new SixLabors.ImageSharp.RectangleF(
                Math.Min(startImagePos.X, currentImagePos.X),
                Math.Min(startImagePos.Y, currentImagePos.Y),
                Math.Abs(startImagePos.X - currentImagePos.X),
                Math.Abs(startImagePos.Y - currentImagePos.Y));

            // 发送选择区域变更事件
            WeakReferenceMessenger.Default.Send(new SelectionChangedEvent(_selectionRect));
        }
		
        private void UpdateSelectionEllipse(Point currentPosition)
        {
            var left = Math.Min(_startPoint.X, currentPosition.X);
            var top = Math.Min(_startPoint.Y, currentPosition.Y);
            var width = Math.Abs(_startPoint.X - currentPosition.X);
            var height = Math.Abs(_startPoint.Y - currentPosition.Y);

            Canvas.SetLeft(SelectionEllipse, left);
            Canvas.SetTop(SelectionEllipse, top);
            SelectionEllipse.Width = width;
            SelectionEllipse.Height = height;
            SelectionEllipse.Visibility = Visibility.Visible;
            SelectionRectangle.Visibility = Visibility.Collapsed;

            // 更新选择区域
            var startImagePos = GetImagePosition(_startPoint);
            var currentImagePos = GetImagePosition(currentPosition);
            
            _selectionRect = new SixLabors.ImageSharp.RectangleF(
                Math.Min(startImagePos.X, currentImagePos.X),
                Math.Min(startImagePos.Y, currentImagePos.Y),
                Math.Abs(startImagePos.X - currentImagePos.X),
                Math.Abs(startImagePos.Y - currentImagePos.Y));

            // 发送选择区域变更事件
            WeakReferenceMessenger.Default.Send(new SelectionChangedEvent(_selectionRect));
        }

        private void UpdateSelectionForAnyPosition(Point currentPosition)
        {
            // 实现任意位置的选择，不限制在左上角
            var centerX = (_startPoint.X + currentPosition.X) / 2;
            var centerY = (_startPoint.Y + currentPosition.Y) / 2;
            var width = Math.Abs(currentPosition.X - _startPoint.X);
            var height = Math.Abs(currentPosition.Y - _startPoint.Y);

            Canvas.SetLeft(SelectionRectangle, centerX - width / 2);
            Canvas.SetTop(SelectionRectangle, centerY - height / 2);
            SelectionRectangle.Width = width;
            SelectionRectangle.Height = height;
            SelectionRectangle.Visibility = Visibility.Visible;

            // 更新选择区域
            var startImagePos = GetImagePosition(_startPoint);
            var currentImagePos = GetImagePosition(currentPosition);
            
            _selectionRect = new SixLabors.ImageSharp.RectangleF(
                Math.Min(startImagePos.X, currentImagePos.X),
                Math.Min(startImagePos.Y, currentImagePos.Y),
                Math.Abs(startImagePos.X - currentImagePos.X),
                Math.Abs(startImagePos.Y - currentImagePos.Y));

            // 发送选择区域变更事件
            WeakReferenceMessenger.Default.Send(new SelectionChangedEvent(_selectionRect));
        }
		
        private void FinishSelection()
        {
            _isSelecting = false;
            
            if (Document != null)
            {
                Document.SelectionArea = _selectionRect;
            }

            WeakReferenceMessenger.Default.Send(new StatusMessageEvent($"Selection: {_selectionRect.Width:0}x{_selectionRect.Height:0}"));
            
            // 保持选择矩形可见
            SelectionRectangle.Visibility = Visibility.Visible;
        }

        private void PerformMagicWandSelection(Point clickPosition)
        {
            if (Document?.Image == null) return;

            var imagePos = GetImagePosition(clickPosition);
            var tolerance = 0.1f; // 颜色容差

            // 使用魔术棒算法选择相似颜色区域
            var selectedPoints = SelectionService.MagicWandSelect(
                Document.Image, 
                (int)imagePos.X, 
                (int)imagePos.Y, 
                tolerance);

            if (selectedPoints.Count > 0)
            {
                // 计算选择区域的边界
                var bounds = SelectionService.GetSelectionBounds(selectedPoints);
                _selectionRect = bounds;
                
                // 更新文档的选择区域
                if (Document != null)
                {
                    Document.SelectionArea = _selectionRect;
                }

                // 发送选择区域变更事件
                WeakReferenceMessenger.Default.Send(new SelectionChangedEvent(_selectionRect));
                WeakReferenceMessenger.Default.Send(new StatusMessageEvent($"Magic Wand Selection: {selectedPoints.Count} pixels selected"));
            }
        }

        #endregion

        #region Measurement Logic

        private void StartMeasurement(Point startPoint)
        {
            _isMeasuring = true;
            MeasurementLine.Visibility = Visibility.Visible;
            MeasurementText.Visibility = Visibility.Visible;
            
            MeasurementLine.X1 = startPoint.X;
            MeasurementLine.Y1 = startPoint.Y;
            MeasurementLine.X2 = startPoint.X;
            MeasurementLine.Y2 = startPoint.Y;
        }

        private void UpdateMeasurement(Point currentPosition)
        {
            MeasurementLine.X2 = currentPosition.X;
            MeasurementLine.Y2 = currentPosition.Y;

            var startImagePos = GetImagePosition(_startPoint);
            var currentImagePos = GetImagePosition(currentPosition);
            
            var distance = Math.Sqrt(
                Math.Pow(currentImagePos.X - startImagePos.X, 2) +
                Math.Pow(currentImagePos.Y - startImagePos.Y, 2));

            MeasurementText.Text = $"{distance:0.0}px";
            Canvas.SetLeft(MeasurementText, 
                (MeasurementLine.X1 + MeasurementLine.X2) / 2);
            Canvas.SetTop(MeasurementText, 
                (MeasurementLine.Y1 + MeasurementLine.Y2) / 2);
        }

        private void FinishMeasurement()
        {
            _isMeasuring = false;
            var startImagePos = GetImagePosition(_startPoint);
            var endImagePos = GetImagePosition(
                new Point(MeasurementLine.X2, MeasurementLine.Y2));
            
            var distance = Math.Sqrt(
                Math.Pow(endImagePos.X - startImagePos.X, 2) +
                Math.Pow(endImagePos.Y - startImagePos.Y, 2));

            WeakReferenceMessenger.Default.Send(new StatusMessageEvent($"Distance: {distance:0.0}px"));
        }

        #endregion

        #region Helper Methods

        private System.Drawing.PointF GetImagePosition(Point controlPosition)
        {
            if (Document?.Image == null) 
                return new System.Drawing.PointF(0, 0);

            var scale = Document.ZoomLevel;
            return new System.Drawing.PointF(
                (float)(controlPosition.X / scale),
                (float)(controlPosition.Y / scale));
        }

        #endregion

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler? PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public void Receive(ImageDocumentChangedEvent message)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}